package com.jc.oms.controller.login;

import com.jc.business.supplier.SupplierBusiness;
import com.jc.business.supplierproduct.SupplierProductBusiness;
import com.jc.common.util.WebUtils;
import com.jc.ds.base.service.BaseServiceException;
import com.jc.ds.mapper.RolePermissionMapper;
import com.jc.ds.model.Permission;
import com.jc.ds.model.RolePermission;
import com.jc.ds.model.User;
import com.jc.ds.model.UserRole;
import com.jc.framework.util.WebConstants;
import com.jc.oms.controller.BaseController;
import com.jc.service.jg.JgService;
import com.jc.service.jg.mq.MqUtil;
import com.jc.service.permission.PermissionService;
import com.jc.service.role.RoleService;
import com.jc.service.rolepermission.RolePermissionService;
import com.jc.service.supplier.SupplierService;
import com.jc.service.user.UserService;
import com.jc.service.userrole.UserRoleService;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.ExcessiveAttemptsException;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.cache.CacheManager;
import org.apache.shiro.session.UnknownSessionException;
import org.apache.shiro.session.mgt.SessionKey;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.web.session.mgt.WebSessionKey;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.Serializable;
import java.io.UnsupportedEncodingException;
import java.text.SimpleDateFormat;
import java.util.*;

@SuppressWarnings("all")
@Controller
@RequestMapping("login")
public class LoginController extends BaseController {
    @Autowired
    SupplierBusiness supplierBusiness;
    @Autowired
    SupplierService supplierService;
    @Autowired
    JgService jgService;
    @Autowired
    SupplierProductBusiness supplierProductBusiness;
    @Autowired
    private UserService userService;
    @Autowired
    private UserRoleService userRoleService;
    @Autowired
    private PermissionService permissionService;
    @Autowired
    private RolePermissionService rolePermissionService;
    @Autowired
    private RoleService roleService;


    @RequestMapping(value = "/queuesize", method = RequestMethod.GET)
    public @ResponseBody
    Map<String, Object> queuesize(HttpServletRequest req) {
        Map<String, Object> _ret = new HashMap<String, Object>();
        _ret.put("size", "队列里还有待保存产品数量 : " + MqUtil.queue.size());
        return _ret;
    }

    @RequestMapping(value = "/getIp", method = RequestMethod.GET)
    public String getIp(HttpServletRequest req) {
        String requestIP = this.getRequestIP(req);
        return requestIP;
    }


    @RequestMapping(value = "/doLogin", method = RequestMethod.POST)
    @ResponseBody
    public Map<String, Object> doLogin(HttpServletRequest request) {
        Map<String, Object> resultMap = new HashMap<>();
        Map<String, Object> param = null;
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        try {
            System.out.println("登录开始时间===========" + sdf.format(new Date()));
            resultMap.put("code", 10000);
            param = WebUtils.ReadAsChars(request);
            if (param.get("userName") == null) {
                throw new BaseServiceException("用户名不能为空");
            }
            if (param.get("passWord") == null) {
                throw new BaseServiceException("密码不能为空");
            }
            String username = param.get("userName").toString();
            String password = param.get("passWord").toString();
            Subject subject = SecurityUtils.getSubject();//获取当前用户对象
            //ThreadContext.remove(ThreadContext.SUBJECT_KEY);//移除线程中的subject
            //生成令牌(传入用户输入的账号和密码)
            UsernamePasswordToken token = new UsernamePasswordToken(username, password);
            //认证登录
            //这里会加载自定义的realm
            System.out.println("登录验证身份！");
            //登录，即身份验证
            subject.login(token);
            User user = (User) subject.getSession().getAttribute(WebConstants.CURRENT_USER);
            System.out.println(user);
            Serializable id = subject.getSession().getId();


            ArrayList<String> btns = new ArrayList<>();

            //查询用户所有的权限
            List<UserRole> userRoles = this.userRoleService.queryAll(new UserRole() {{
                setUserId(user.getId());
            }});
            if (userRoles.size() < 1) throw new BaseServiceException("当前用户没有任何权限！请联系管理员。");

//            if (userRoles.size() > 1)throw new BaseServiceException("【系统异常】当前用户拥有多个角色！");
            //查询所有的按钮
            List<Permission> permissions = permissionService.queryAll(new Permission() {{
                setPermissionType(0);
            }});

            Set<Long> roleIds = new HashSet<>();
            //查询role菜单关联表
            for (UserRole userRole : userRoles) {
                List<RolePermission> rolePermissions = rolePermissionService.queryAll(new RolePermission() {{
                    setRoleId(userRole.getRoleId());
                }});
                for (RolePermission rolePermission : rolePermissions) {
                    roleIds.add(rolePermission.getPermissionId());
                }
            }
            for (Long rolePermission : roleIds) {
                for (Permission permission : permissions) {
                    if (rolePermission.toString().equals(permission.getId().toString())) {
                        btns.add(permission.getCode());
                    }
                }
            }
            System.out.println("登录结束时间: " + sdf.format(new Date()));
//            userRoles.forEach(userRole -> {
//                List<Role> roles = this.roleService.queryAll(new Role() {{
//                    setId(userRole.getRoleId());
//                }});
//                roles.forEach(role -> {
//                    List<RolePermission> rolePermissions = this.rolePermissionMapper.selectAll(new RolePermission() {{
//                        setRoleId(role.getId());
//                    }});
//                    rolePermissions.forEach(rolePermission -> {
//                        List<Permission> permissions = this.permissionService.queryAll(new Permission() {{
//                            setId(rolePermission.getPermissionId());
//                            setPermissionType(0);
//                        }});//查询出来所有拥有的按钮的权限
//                        permissions.forEach(permission -> {
//                            btns.add(permission.getCode());
//                        });
//
//                    });
//                });
//            });
            System.out.println("btns = " + btns);
            resultMap.put("data", new HashMap<String, Object>() {{
                put("token", id);
                put("name", user.getName());
                put("btns", btns);
                put("userId", user.getId());
            }});
        } catch (UnsupportedEncodingException e) {
            resultMap.put("code", 9999);
            resultMap.put("msg", e.getLocalizedMessage());
            e.printStackTrace();
        } catch (UnknownAccountException uae) {
            resultMap.put("code", 9999);
            resultMap.put("msg", uae.getLocalizedMessage());
            uae.printStackTrace();
        } catch (IncorrectCredentialsException ice) {
            resultMap.put("code", 9999);
            resultMap.put("msg", "密码输入错误!");
            ice.printStackTrace();
        } catch (ExcessiveAttemptsException e) {
            resultMap.put("code", 9999);
            resultMap.put("msg", "账号登录错误次数太多,已被锁定");
            e.printStackTrace();
        } catch (UnknownSessionException u) {
            //session失效

        } catch (BaseServiceException b) {
            resultMap.put("code", 9999);
            resultMap.put("msg", b.getMessage());
            b.printStackTrace();
        }
        return resultMap;
    }

    @Autowired
    private CacheManager cacheManager;

    @RequestMapping(value = "/checkLoginStatus", method = RequestMethod.POST)
    @ResponseBody
    public Map<String, Object> checkLoginStatus(HttpServletRequest request, HttpServletResponse response) {
        Map<String, Object> resultMap = new HashMap<>();
        Map<String, Object> param = null;
        try {
            resultMap.put("code", 10000);
            param = WebUtils.ReadAsChars(request);

            if (param.get("token") == null) {
                throw new BaseServiceException("token不能为空");
            }

            SessionKey key = new WebSessionKey(param.get("token").toString(), request, response);
            User user = (User) SecurityUtils.getSecurityManager().getSession(key).getAttribute(WebConstants.CURRENT_USER);
            if (user == null) {
                resultMap.put("code", 4000);
                resultMap.put("msg", "登录失效");
                return resultMap;
            }
            resultMap.put("data", user);
        } catch (UnknownSessionException use) {
/*			SessionKey key = new WebSessionKey(param.get("token").toString(),request,response);
			Session session = SecurityUtils.getSecurityManager().getSession(key);
			String sessionid = session.getId().toString();
			cacheManager.getCache("shiro-activeSessionCache").remove(sessionid);*/
            resultMap.put("code", 4000);
            resultMap.put("msg", "登录失效");
            use.printStackTrace();
        } catch (Exception ice) {
            resultMap.put("code", 9999);
            resultMap.put("msg", ice.getLocalizedMessage());
            ice.printStackTrace();
        }
        return resultMap;
    }


    @RequestMapping(value = "/loginOut", method = RequestMethod.POST)
    @ResponseBody
    public Map<String, Object> loginOut(HttpServletRequest request, HttpServletResponse response) {
        Map<String, Object> resultMap = new HashMap<>();
        Map<String, Object> param = null;
        try {
            param = WebUtils.ReadAsChars(request);
            if (param == null || StringUtils.isEmpty(param.get("token").toString())) {
                throw new BaseServiceException("缺少必传参数!");
            }
            SessionKey key = new WebSessionKey(param.get("token").toString(), request, response);
            SecurityUtils.getSecurityManager().getSession(key).removeAttribute(WebConstants.CURRENT_USER);
        } catch (UnknownSessionException use) {
            resultMap.put("code", 4000);
            resultMap.put("msg", "登录已失效");
            use.printStackTrace();
        } catch (UnsupportedEncodingException e) {
            resultMap.put("code", 9999);
            resultMap.put("msg", e.getLocalizedMessage());
            e.printStackTrace();
        }
        return resultMap;
    }
}
